/**
 * DESC:
 * bom2xml:map对象到xml文本
 * 以映射metaMap<String, MClass> 为依据，map中的属性或map对象的key不和field.name相同就放弃
 * xml2bom:xml文本到map对象
 * 以映射metaMap<String, MClass> 为依据，xml中的标签名称和field.name相同就放弃
 * 顶层对象insertMap  只有 IN,OUT,ALL 等类型的可以作为顶层对象的二级对象
 */
package com.tansun.rule.utils;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.tansun.rule.config.AppConfiguration;
import com.tansun.rule.exception.ConvertException;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.MField;
import com.tansun.rule.utils.MathHelper;
import com.tansun.rule.utils.RuleBomMapXmlConvert;
@SuppressWarnings("unchecked")
public class RuleBomMapXmlConvertProject extends RuleBomMapXmlConvert {

	private static MClass systemMClass = null;
	private static MClass resultMClass = null;
	
	static{
		String path = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + 
				"<resultMapping>\r\n" + 
				"	<class id=\"system\" name=\"System\" paramType=\"OUT\" chzn=\"系统信息\" desc=\"\">\r\n" + 
				"	</class>\r\n" + 
				"	<class id=\"rer\" name=\"RuleExecutResult\" chzn=\"执行结果\" desc=\"\">\r\n" + 
				"	</class>\r\n" + 
				"</resultMapping>";
		Map<String, MClass> map = RuleBomMapXmlConvert.getMapping(path);
		systemMClass = map.get("System");
		resultMClass = map.get("RuleExecutResult");
	}
	
	/**
	 * 按照规则项目转换
	 * @param ruleProject
	 * @param inputXml
	 * @return
	 * @throws ConvertException
	 */
	public Map<String, Object> convertBusinessMap(String ruleProject, String inputXml) throws ConvertException{
		try {
			if(AppConfiguration.RuleProjMetaMap.get(ruleProject) == null){
				//String path = AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir+"/"+ruleProject+"/"+AppConfiguration.BomFile;
				String path = AppConfiguration.RuleProjDeployDir+"/"+ruleProject+"/"+AppConfiguration.BomFile;
				File filemap = new File(path);
				Map<String, MClass> metaMap = getMapping(filemap);
				//规则执行系统信息
				metaMap.put("System", buildSystemMClass());
				
				AppConfiguration.RuleProjMetaMap.put(ruleProject, metaMap);
			}
			
			Map convertinsertMap = xml2bom(inputXml,AppConfiguration.RuleProjMetaMap.get(ruleProject),true);
			return convertinsertMap;
		} catch (Exception e) {
			e.printStackTrace();
			throw new ConvertException("convert xml to bom error");
		}
	}
	
	
	/**
	 * 额外转换信息
	 * @return
	 */
	private static MClass buildSystemMClass(){
		
		
		MClass mclass = new MClass();
		mclass.setName("System");
		mclass.setParamType("OUT");
		mclass.setChzn("执行信息");
		
		MField mfield0 = new MField();
		mfield0.setName("entryPoint");
		mfield0.setType("String");
		MField mfield1 = new MField();
		mfield1.setName("invokeTimes");
		mfield1.setType("Long");
		MField mfield2 = new MField();
		mfield2.setName("isSuccess");
		mfield2.setType("String");
		MField mfield3 = new MField();
		mfield3.setName("exception");
		mfield3.setType("String");
		MField mfield4 = new MField();
		mfield4.setName("exceptiontType");
		mfield4.setType("String");
		MField mfield5 = new MField();
		mfield5.setName("id");
		mfield5.setType("String");
		
		mclass.getFieldMap().put("entryPoint", mfield0);
		mclass.getmFieldNames().add("entryPoint");
		mclass.getFieldMap().put("invokeTimes", mfield1);
		mclass.getmFieldNames().add("invokeTimes");
		mclass.getFieldMap().put("isSuccess", mfield2);
		mclass.getmFieldNames().add("isSuccess");
		mclass.getFieldMap().put("exception", mfield3);
		mclass.getmFieldNames().add("exception");
		mclass.getFieldMap().put("exceptiontType", mfield4);
		mclass.getmFieldNames().add("exceptiontType");
		mclass.getFieldMap().put("id", mfield5);
		mclass.getmFieldNames().add("id");
		return  mclass;
	}
	/**
	 * 按照规则项目转换
	 * 
	 * @param ruleProject
	 * @param outMap
	 * @return
	 */
	public String convertBusinessXml(String ruleProject, Map<String, Object> outMap){
		
//		if(AppConfiguration.RuleProjMetaMap.get(ruleProject) == null){
//			String path = AppConfiguration.APPHOMEDIR+AppConfiguration.RuleProjDeployDir+"/"+ruleProject+"/"+AppConfiguration.BomFile;
//			File filemap = new File(path);
//		}
		//规则执行系统信息
		if(AppConfiguration.RuleProjMetaMap.get(ruleProject).get("System")==null){
			Map<String, MClass> metaMap = AppConfiguration.RuleProjMetaMap.get(ruleProject);
			metaMap.put("System", systemMClass);
			metaMap.put("RuleExecutResult", resultMClass);
			AppConfiguration.RuleProjMetaMap.put(ruleProject, metaMap);
			
		}
//		
//		Set<String> keys = outMap.keySet();
//		for (String key : keys) {
//			
//		}
//		
		
		String xml = bom2xml(outMap, AppConfiguration.RuleProjMetaMap.get(ruleProject), true);
		return xml;
	}
	
	/**
	 * 衍生变量计算
	 * @param dataMap
	 * @param metaMap
	 */
	public static void doDerives(Map<String, Object> dataMap, String ruleProject){
		Map<String, MClass> metaMap = AppConfiguration.RuleProjMetaMap.get(ruleProject);
		HashMap<String, Object> mathMap = new HashMap<String, Object>();
		
		Set<String> ckeys = metaMap.keySet();
		for (String mclassname : ckeys) {
			Map<String, MField> mfMap = metaMap.get(mclassname).getFieldMap();
			
			Set<String> fkeys = mfMap.keySet();
			for (String mfieldname : fkeys) {
				Object subDataMap = dataMap.get(mclassname);
				if(subDataMap!=null){
					mathMap.put(mfMap.get(mfieldname).getId(), ((Map<String, Object>)subDataMap).get(mfieldname));
					
				}
			}
		}
		for (String mclassname : ckeys) {
			Map<String, MField> mfMap = metaMap.get(mclassname).getFieldMap();
			
			Set<String> fkeys = mfMap.keySet();
			for (String mfieldname : fkeys) {
				if("true".equalsIgnoreCase(mfMap.get(mfieldname).getIsDerives())){
					Object result = MathHelper.invokeMath(mathMap,  mfMap.get(mfieldname).getMathStr());
					((Map<String, Object>)dataMap.get(mclassname)).put(mfieldname, result);
				}
			}
		}
		
	}
	
	
	public static void main(String[] args) throws Exception {
		
/*生成模拟模拟map*/
		File filemap = new File("G:/drools/droolsWS/MyDroolsProj9/RuleBomMapping.xml");
		Map<String, MClass> metaMap = getMapping(filemap);
		metaMap.put("System", systemMClass);
//		
		metaMap.put("RuleExecutResult", resultMClass);
		System.out.println(metaMap.keySet().size());
		RuleBomMapXmlConvertProject ruleBomMapXmlConvert = new RuleBomMapXmlConvertProject();
		Map<String, Object> insertMap = ruleBomMapXmlConvert.buildMap(metaMap,false);
//		Map<String, Object> testmap = (Map<String, Object>)insertMap.get("PersonalInfo");
//		testmap.put("aaa", "bbbb");
//		testmap.remove("providerNum");
//		testmap.put("yearIncome", null);//.remove("providerNum");
		System.out.println("模拟Map对象------------------------");
		System.out.println(insertMap);
		Map mmm = (Map)((List)(((Map)(insertMap.get("System"))).get("ruleExecutResultList"))).get(0);
		mmm.remove("info9");
		mmm.remove("info8");
		mmm.remove("info7");
		mmm.remove("info6");
		mmm.remove("info5");
		mmm.remove("info4");
		mmm.remove("info3");
		mmm.remove("info2");
		System.out.println("模拟Map对象 to xml------------------------");
		String xml = bomAll2xml(insertMap, metaMap, true);
		System.out.println(xml);
		
		System.out.println("xml to 模拟Map对象 ------------------------");
		Map convertinsertMap = xml2bom(xml,metaMap,true);
		//Map convertinsertMap2 = bomAll2xml(xml,metaMap,true);
		System.out.println(convertinsertMap);
		System.out.println("---------------------------");
		
		
		
	}
}
